#include <iostream>
#include <cstdlib>
#include "list_ss.h"
#include <sstream>
#include <set>
#include <iterator>

using namespace std;
using namespace tr1;

VECTOR_LIST list::remove(list::el * element) {
	//cerr << "remove called for element: " << (*element).element << endl;
	BUCKET * empty = NULL;
	//cerr << "#elements before erase:" << elements.size() << endl;
	//cerr << "Element found" << (this->elements.find(element) != elements.end()) << endl;

	elements.erase(element);
	//cerr << "#elements after erase:" << elements.size() << endl;
	VECTOR_LIST result = VECTOR_LIST();

	if (this->elements.size() == 0) {
		if (prev == this || next == this) {
			result.push_back(empty);
			result.push_back(empty);
		} else {
			result.push_back(prev);
			result.push_back(next);
		}

	} else {
		result.push_back(this);
		result.push_back(next);
	}
	return result;

} //A function used to create a new element in the list with a return type element*


void list::add(EL * el) {
	//cerr << "add element t:" << (*el).element << endl;
	//cerr << "#elements before insert:" << this->elements.size() << endl;

	this->elements.insert(el);

	(*el).assign(this);
	//cerr << "ASSIGN DONE" << endl;
	//cerr << "#elements after insert:" << this->elements.size() << endl;
	//cerr << "inserted into elements" << endl;
} //A function used to search for elements in the list with a return type element*

void list::set_prev(BUCKET * _prev) {
	this->prev = _prev;
}
void list::set_next(BUCKET * _next) {
	this->next = _next;
}

TUPLE_LIST_EL list::replace_min() {
	//cerr << "updating min" <<endl;
	BUCKET * empty = NULL;
	EL * old = (*this->elements.begin());
	this->elements.erase(old);

	//cerr << "#elements after erase:" << elements.size() << endl;
	TUPLE_LIST_EL result;

	if (this->elements.size() == 0) {
		if (prev == this || next == this) {
			result = TUPLE_LIST_EL(empty, empty, old);
		} else {
			result = TUPLE_LIST_EL(prev, next, old);
		}

	} else {
		result = TUPLE_LIST_EL(this, next, old);
	}
	return result;
}

set<EL*> list::get_elements() {
	return elements;
}

bool list::isEmpty() {
	return (elements.size() == 0);
}

string list::to_string() {

	stringstream out;
	out << "Count=" << count << "  Prev=" << (*prev).count << "  Next=" << (*next).count << "\n";
	out << "[";
	set<EL*>::iterator it = elements.begin();
	for (it; it != elements.end();it++) {
		out << (*(*it)).to_string() << ",";
	}
	out << "]";
	return out.str();
}

list::list(BUCKET * prev, BUCKET * next) {
	//cerr << "prev" << (prev == NULL)<< endl;
	//cerr << "next" << (next == NULL)<< endl;

	this->count = 1;
	if (prev == NULL && next == NULL) {
		this->prev = this;
		this->next = this;
	} else {
		this->prev = prev;
		this->next = next;
	}
}

list::list(BUCKET * prev, BUCKET * next, int count) {
	this->count = count;
	if (prev == NULL && next == NULL) {
		this->prev = this;
		this->next = this;
	} else {
		this->prev = prev;
		this->next = next;
	}
}

list::~list() {}
